<?php

namespace app\admin\service\admin;

use app\admin\model\admin\File as FileModel;
use Raiseinfo\Tools;
use think\exception\ValidateException;
use think\facade\Filesystem;
use think\facade\Validate;
use utils\oss\OssService;

class FileService
{
    /**
     * 执行上传操作
     * @param $file
     * @return array
     */
    public static function doUpload(&$file, $edit = null): array
    {

        // 确定是否允许上传到OSS
        $enableOss = config('rds.upload_enable_oss');
        if ($enableOss === 1) {
            // 上传到OSS
            $data = [
                'tmp_name' => $file->getPathname(), // 本地临时文件
                'extension' => $file->extension(),  // 上传文件的扩展名
            ];
            $url = OssService::handleOssUpload($data);
        } else {
            // 本地服务器上传
            $url = self::uploadToLocalServer($file);
        }
        // 将上传的文件存储到数据库
        $fileInfo = self::addFile($file, $url, $edit);
        // 返回文件对象
        return $fileInfo;

    }

    /**
     * 添加文件记录
     * @param $file
     * @param $url
     * @return array
     */
    public static function addFile(&$file, $url, $edit = null): array
    {
        $hash = $file->hash('md5');
        $data = [
            'url' => $url,
            'hash' => $hash,
            'extension' => $file->getOriginalExtension(),
            'name' => $file->getOriginalName(),
            'mime' => $file->getOriginalMime(),
            'size' => $file->getSize(),
            'edit' => $edit,
        ];
        $fileInfo = FileModel::create($data);
        return $fileInfo->toArray();
    }


    /**
     * @param $file
     * @return mixed|string
     */
    public static function getSameFileUrl(&$file): mixed
    {
        $fileInfo = FileModel::where('hash', $file->md5())->findOrEmpty();
        if (!$fileInfo->isEmpty() && config('rds.upload_file_unique')) {
            return $fileInfo;
        } else {
            return '';
        }
    }

    /**
     * 上传到本地服务器
     * @param $file
     * @return string
     */
    public static function uploadToLocalServer(&$file): string
    {
        $file_path = app('http')->getName() . DIRECTORY_SEPARATOR . date(config('rds.upload_sub_dir'));
        $filename = Filesystem::disk('public')->putFile($file_path, $file, 'uniqid');
        $url = config('filesystem.disks.public.url') . DIRECTORY_SEPARATOR . $filename;
        return $url;
    }

    /**
     * 对上传的文件进行检查
     * 1.扩展名
     * 2.大小
     * @param $file
     * @return void
     */
    public static function validateFileType(&$file): void
    {
        // 扩展名检查
        $originName = $file->getOriginalName();
        $tools = new Tools();
        // 过滤黑名单
        if ($tools->uploadFilter($originName)) {
            $extensionList = implode(',', config('rds.upload_file_extension'));
            $mimeList = implode(',', config('rds.upload_file_mime'));
            // 检查扩展名和mime文件
            if (!Validate::fileExt($file, $extensionList) && !Validate::fileMime($file, $mimeList)) {
                throw new ValidateException('文件类型验证失败');
            }
            // 文件大小检查
            if (!Validate::fileSize($file, config('rds.upload_max_size') * 1024 * 1024)) {
                throw new ValidateException('文件大小验证失败');
            }
        } else {
            throw new ValidateException('黑名单文件禁止上传');
        }
    }
}